<!-- 实现微信服务号自动回复功能
1.被关注回复

数据库设计如下：
id 主键自增
replyType 自动回复类型 1.被关注回复 2.收到消息回复 3.关键字回复
replyContent 回复内容 文本、图片、语音、视频、文件、链接, 图文等
replyContentType 回复内容类型 1.文本 2.图片 3.语音 4.视频 5.音乐 6.图文
replyState 回复状态 1.启用 0.禁用
ctime 创建时间
utime 更新时间
dtime 删除时间 -->

<template>
  <div class="follow-reply-container">
    <div class="reply-type-content">
      <div class="state-switch">
        <span>状态：</span>
        <el-switch 
          v-model="followReply.replyState" 
          active-value="1" 
          inactive-value="0"
          @change="handleStateChange"
        />
        <span class="state-text">{{ followReply.replyState === '1' ? '已启用' : '已禁用' }}</span>
      </div>
      
      <div class="content-type-selector">
        <span>回复内容类型：</span>
        <el-select 
          v-model="followReply.replyContentType" 
          placeholder="请选择回复内容类型"
          @change="handleContentTypeChange"
        >
          <el-option label="文本" value="1" />
          <el-option label="图片" value="2" />
          <el-option label="语音" value="3" />
          <el-option label="视频" value="4" />
          <el-option label="音乐" value="5" />
          <el-option label="图文" value="6" />
        </el-select>
      </div>

      <!-- 内容编辑区域 -->
      <div class="content-editor" v-if="followReply.replyState === '1'">
        <!-- 文本内容 -->
        <div v-if="followReply.replyContentType === '1'" class="content-item">
          <el-input
            type="textarea"
            :rows="5"
            placeholder="请输入文本内容"
            v-model="followReply.replyContent.text"
            maxlength="600"
            show-word-limit
          />
        
        </div>

        <!-- 图片内容 -->
        <div v-if="followReply.replyContentType === '2'" class="content-item">
          <div class="upload-wrapper">
            <el-upload
              class="avatar-uploader"
              action="#"
              :show-file-list="false"
              :before-upload="beforeImageUpload"
              :http-request="handleImageUpload"
            >
              <img v-if="followReply.replyContent.imageUrl" :src="followReply.replyContent.imageUrl" class="avatar">
              <i v-else class="el-icon-plus avatar-uploader-icon"></i>
            </el-upload>
            <div v-if="followReply.replyContent.imageUrl" class="upload-actions">
              <el-button type="text" size="small" @click="viewImage">查看</el-button>
              <el-button type="text" size="small" danger @click="removeImage">删除</el-button>
            </div>
          </div>
          <div class="content-tips">支持JPG、PNG格式，大小不超过2MB</div>
        </div>

        <!-- 语音内容 -->
        <div v-if="followReply.replyContentType === '3'" class="content-item">
          <el-upload
            class="file-uploader"
            action="#"
            :show-file-list="true"
            accept=".mp3,.wma,.wav,.amr"
            :before-upload="beforeVoiceUpload"
            :http-request="handleVoiceUpload"
          >
            <el-button size="small" type="primary">点击上传</el-button>
          </el-upload>
          <div class="content-tips">支持MP3、WMA、WAV、AMR格式，大小不超过5MB，时长不超过60秒</div>
        </div>

        <!-- 视频内容 -->
        <div v-if="followReply.replyContentType === '4'" class="content-item">
          <el-upload
            class="file-uploader"
            action="#"
            :show-file-list="true"
            accept=".mp4"
            :before-upload="beforeVideoUpload"
            :http-request="handleVideoUpload"
          >
            <el-button size="small" type="primary">点击上传</el-button>
          </el-upload>
          <div class="content-tips">支持MP4格式，大小不超过10MB</div>
        </div>

        <!-- 音乐内容 -->
        <div v-if="followReply.replyContentType === '5'" class="content-item">
          <el-form :model="followReply.replyContent">
            <el-form-item label="标题" prop="title">
              <el-input v-model="followReply.replyContent.title" placeholder="请输入音乐标题" />
            </el-form-item>
            <el-form-item label="描述" prop="description">
              <el-input v-model="followReply.replyContent.description" placeholder="请输入音乐描述" />
            </el-form-item>
            <el-form-item label="音乐链接" prop="musicUrl">
              <el-input v-model="followReply.replyContent.musicUrl" placeholder="请输入音乐链接" />
            </el-form-item>
            <el-form-item label="HQ音乐链接" prop="hqMusicUrl">
              <el-input v-model="followReply.replyContent.hqMusicUrl" placeholder="请输入高品质音乐链接" />
            </el-form-item>
            <el-form-item label="缩略图" prop="thumbMediaId">
              <el-upload
                class="avatar-uploader"
                action="#"
                :show-file-list="false"
                :before-upload="beforeAvatarUpload"
                :http-request="handleThumbUpload"
              >
                <img v-if="followReply.replyContent.thumbUrl" :src="followReply.replyContent.thumbUrl" class="avatar">
                <i v-else class="el-icon-plus avatar-uploader-icon"></i>
              </el-upload>
            </el-form-item>
          </el-form>
        </div>

        <!-- 图文内容 -->
        <div v-if="followReply.replyContentType === '6'" class="content-item">
          <el-button type="primary" size="small" @click="addNewsItem" :disabled="followReply.replyContent.newsList.length >= 8">添加图文</el-button>
          <div class="news-list">
            <div v-for="(news, index) in followReply.replyContent.newsList" :key="index" class="news-item">
              <div class="news-header">
                <span class="news-index">第{{ index + 1 }}条</span>
                <el-button type="danger" size="small" @click="removeNewsItem(index)" v-if="followReply.replyContent.newsList.length > 1">删除</el-button>
              </div>
              <el-form :model="news">
                <el-form-item label="标题" :prop="`newsList[${index}].title`">
                  <el-input v-model="news.title" placeholder="请输入标题" maxlength="64" show-word-limit />
                </el-form-item>
                <el-form-item label="描述" :prop="`newsList[${index}].description`">
                  <el-input v-model="news.description" placeholder="请输入描述" maxlength="120" show-word-limit />
                </el-form-item>
                <el-form-item label="图片" :prop="`newsList[${index}].picUrl`">
                  <el-upload
                    class="avatar-uploader"
                    action="#"
                    :show-file-list="false"
                    :before-upload="beforeAvatarUpload"
                    :http-request="(options) => handleNewsImageUpload(options, index)"
                  >
                    <img v-if="news.picUrl" :src="news.picUrl" class="avatar">
                    <i v-else class="el-icon-plus avatar-uploader-icon"></i>
                  </el-upload>
                </el-form-item>
                <el-form-item label="链接" :prop="`newsList[${index}].url`">
                  <el-input v-model="news.url" placeholder="请输入链接" />
                </el-form-item>
              </el-form>
            </div>
          </div>
          <div class="content-tips">最多支持8条图文消息</div>
        </div>
      </div>
      
      <div class="action-buttons">
        <el-button type="primary" @click="handleSave">保存</el-button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, watch } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { http } from '@/utils/servers';

// 被关注回复数据
const followReply = reactive({
  id: '',
  replyType: '1',
  replyContent: { text: '' },
  replyContentType: '1',
  replyState: '1',

});

// 初始化数据
const initData = () => {
  // 获取被关注回复设置
  http.get('/api/wechat/autoReply/getByType', {
    params: { replyType: 1 }
  }).then(res => {
    if (res.success && res.data) {
      const data = res.data;
      followReply.id = data.id;
      followReply.replyType = data.replyType;
      followReply.replyContentType = data.replyContentType;
      followReply.replyState = data.replyState;

      
      // 解析回复内容
      try {
        followReply.replyContent = JSON.parse(data.replyContent || '{}');
      } catch (error) {
        followReply.replyContent = {};
      }
      
      // 初始化不同类型的默认内容结构
      handleContentTypeChange();
    }
  }).catch(error => {
    console.error('获取被关注回复设置失败:', error);
    ElMessage.error('获取被关注回复设置失败');
  });
};

// 处理状态变化
const handleStateChange = () => {
  ElMessage.info(`被关注回复已${followReply.replyState === '1' ? '启用' : '禁用'}`);
};

// 处理内容类型变化
const handleContentTypeChange = () => {
  // 根据内容类型初始化对应的内容结构
  const contentType = followReply.replyContentType;
  switch (contentType) {
    case '1':
      if (!followReply.replyContent.text) {
        followReply.replyContent.text = '';
      }
      break;
    case '2':
      if (!followReply.replyContent.imageUrl) {
        followReply.replyContent.imageUrl = '';
      }
      break;
    case '3':
      if (!followReply.replyContent.voiceUrl) {
        followReply.replyContent.voiceUrl = '';
      }
      break;
    case '4':
      if (!followReply.replyContent.videoUrl) {
        followReply.replyContent.videoUrl = '';
      }
      break;
    case '5':
      if (!followReply.replyContent.title) {
        followReply.replyContent = {
          title: '',
          description: '',
          musicUrl: '',
          hqMusicUrl: '',
          thumbMediaId: '',
          thumbUrl: ''
        };
      }
      break;
    case '6':
      if (!followReply.replyContent.newsList || !Array.isArray(followReply.replyContent.newsList)) {
        followReply.replyContent.newsList = [{
          title: '',
          description: '',
          picUrl: '',
          url: ''
        }];
      }
      break;
  }
};

// 图片上传前检查
const beforeImageUpload = (file) => {
  const isLt2M = file.size / 1024 / 1024 < 2;
  const isImage = file.type.startsWith('image/');
  
  if (!isImage) {
    ElMessage.error('请上传图片文件!');
    return false;
  }
  if (!isLt2M) {
    ElMessage.error('上传图片大小不能超过 2MB!');
    return false;
  }
  return true;
};

// 语音上传前检查
const beforeVoiceUpload = (file) => {
  const isLt5M = file.size / 1024 / 1024 < 5;
  const validTypes = ['.mp3', '.wma', '.wav', '.amr'];
  const isValidType = validTypes.some(type => file.name.toLowerCase().endsWith(type));
  
  if (!isValidType) {
    ElMessage.error('请上传MP3、WMA、WAV、AMR格式的语音文件!');
    return false;
  }
  if (!isLt5M) {
    ElMessage.error('上传语音大小不能超过 5MB!');
    return false;
  }
  return true;
};

// 视频上传前检查
const beforeVideoUpload = (file) => {
  const isLt10M = file.size / 1024 / 1024 < 10;
  const isMP4 = file.name.toLowerCase().endsWith('.mp4');
  
  if (!isMP4) {
    ElMessage.error('请上传MP4格式的视频文件!');
    return false;
  }
  if (!isLt10M) {
    ElMessage.error('上传视频大小不能超过 10MB!');
    return false;
  }
  return true;
};

// 缩略图上传前检查
const beforeAvatarUpload = beforeImageUpload;

// 处理图片上传
const handleImageUpload = (options) => {
  const file = options.file;
  // 实际项目中应该调用上传API
  // 这里使用模拟数据
  setTimeout(() => {
    // 模拟上传成功
    followReply.replyContent.imageUrl = URL.createObjectURL(file);
    ElMessage.success('图片上传成功');
    options.onSuccess({ status: 200 });
  }, 1000);
};

// 处理语音上传
const handleVoiceUpload = (options) => {
  // 实际项目中应该调用上传API
  setTimeout(() => {
    followReply.replyContent.voiceUrl = options.file.name;
    ElMessage.success('语音上传成功');
    options.onSuccess({ status: 200 });
  }, 1000);
};

// 处理视频上传
const handleVideoUpload = (options) => {
  // 实际项目中应该调用上传API
  setTimeout(() => {
    followReply.replyContent.videoUrl = options.file.name;
    ElMessage.success('视频上传成功');
    options.onSuccess({ status: 200 });
  }, 1000);
};

// 处理缩略图上传
const handleThumbUpload = (options) => {
  const file = options.file;
  // 实际项目中应该调用上传API
  setTimeout(() => {
    followReply.replyContent.thumbUrl = URL.createObjectURL(file);
    ElMessage.success('缩略图上传成功');
    options.onSuccess({ status: 200 });
  }, 1000);
};

// 处理图文图片上传
const handleNewsImageUpload = (options, index) => {
  const file = options.file;
  // 实际项目中应该调用上传API
  setTimeout(() => {
    followReply.replyContent.newsList[index].picUrl = URL.createObjectURL(file);
    ElMessage.success('图片上传成功');
    options.onSuccess({ status: 200 });
  }, 1000);
};

// 查看图片
const viewImage = () => {
  if (followReply.replyContent.imageUrl) {
    // 实际项目中可以使用图片预览组件
    window.open(followReply.replyContent.imageUrl, '_blank');
  }
};

// 删除图片
const removeImage = () => {
  ElMessageBox.confirm('确定要删除当前图片吗？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    followReply.replyContent.imageUrl = '';
    ElMessage.success('图片已删除');
  }).catch(() => {
    // 用户取消删除
  });
};

// 添加图文项
const addNewsItem = () => {
  if (followReply.replyContent.newsList.length >= 8) {
    ElMessage.warning('最多支持8条图文消息');
    return;
  }
  const newNews = {
    title: '',
    description: '',
    picUrl: '',
    url: ''
  };
  followReply.replyContent.newsList.push(newNews);
  ElMessage.success('图文消息已添加');
};

// 删除图文项
const removeNewsItem = (index) => {
  ElMessageBox.confirm('确定要删除这条图文消息吗？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    followReply.replyContent.newsList.splice(index, 1);
    ElMessage.success('图文消息已删除');
  }).catch(() => {
    // 用户取消删除
  });
};

// 验证内容
const validateContent = () => {
  if (followReply.replyState === '0') {
    return true;
  }
  
  switch (followReply.replyContentType) {
    case '1':
      if (!followReply.replyContent.text || followReply.replyContent.text.trim() === '') {
        ElMessage.warning('请输入文本内容');
        return false;
      }
      break;
    case '2':
      if (!followReply.replyContent.imageUrl) {
        ElMessage.warning('请上传图片');
        return false;
      }
      break;
    case '3':
      if (!followReply.replyContent.voiceUrl) {
        ElMessage.warning('请上传语音');
        return false;
      }
      break;
    case '4':
      if (!followReply.replyContent.videoUrl) {
        ElMessage.warning('请上传视频');
        return false;
      }
      break;
    case '5':
      const { title, musicUrl, thumbMediaId } = followReply.replyContent;
      if (!title || !musicUrl || !thumbMediaId) {
        ElMessage.warning('请填写完整的音乐信息');
        return false;
      }
      break;
    case '6':
      const { newsList } = followReply.replyContent;
      if (!newsList || newsList.length === 0) {
        ElMessage.warning('请添加至少一条图文消息');
        return false;
      }
      // 验证每条图文消息
      for (let i = 0; i < newsList.length; i++) {
        const news = newsList[i];
        if (!news.title || !news.picUrl || !news.url) {
          ElMessage.warning(`第${i + 1}条图文消息请填写完整信息`);
          return false;
        }
      }
      break;
  }
  return true;
};

// 保存设置
const handleSave = () => {
  if (!validateContent()) {
    return;
  }
  
  // 准备保存数据
  const saveData = {
    id: followReply.id,
    replyType: followReply.replyType,
    replyContent: JSON.stringify(followReply.replyContent),
    replyContentType: followReply.replyContentType,
    replyState: followReply.replyState
  };
  
  // 保存到服务器
  http.post('/api/wechat/autoReply/save', saveData).then(res => {
    if (res.success) {
      ElMessage.success('被关注回复设置保存成功');
      // 如果是新增，更新ID
      if (!followReply.id) {
        followReply.id = res.data.id;
      }
      // 更新更新时间
      followReply.utime = new Date().toISOString();
    } else {
      ElMessage.error(res.message || '保存失败');
    }
  }).catch(error => {
    console.error('保存被关注回复设置失败:', error);
    ElMessage.error('保存失败，请稍后重试');
  });
};

// 初始化
// initData();
</script>

<style scoped lang="scss">
.follow-reply-container {
  width: 100%;
}

.reply-type-content {
  margin-top: 20px;
}

.state-switch {
  margin-bottom: 20px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.state-text {
  color: #606266;
}

.content-type-selector {
  margin-bottom: 20px;
  display: flex;
  align-items: center;
  gap: 10px;
  span {
    text-align: left;
    width: 120px;
  }
}

.content-editor {
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  padding: 20px;
  background-color: #fafafa;
}

.content-item {
  margin-bottom: 15px;
}

.content-tips {
  color: #909399;
  font-size: 12px;
  margin-top: 8px;
}

/* 图片上传样式 */
.upload-wrapper {
  position: relative;
  display: inline-block;
}

.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  background-color: #fff;
}

.avatar-uploader .el-upload:hover {
  border-color: #409eff;
}

.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  line-height: 178px;
  text-align: center;
}

.avatar {
  width: 178px;
  height: 178px;
  display: block;
}

.upload-actions {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  background: rgba(0, 0, 0, 0.5);
  color: #fff;
  text-align: center;
  padding: 5px 0;
  display: flex;
  justify-content: center;
  gap: 15px;
}

.upload-actions .el-button {
  color: #fff;
}

.file-uploader {
  margin-bottom: 10px;
}

/* 图文列表样式 */
.news-list {
  margin-top: 15px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.news-item {
  padding: 15px;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  background-color: #fff;
}

.news-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
  padding-bottom: 10px;
  border-bottom: 1px solid #f0f0f0;
}

.news-index {
  font-weight: 500;
  color: #606266;
}

/* 操作按钮样式 */
.action-buttons {
  margin-top: 30px;
  display: flex;
  gap: 10px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .state-switch,
  .content-type-selector {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }
  
  .avatar-uploader-icon,
  .avatar {
    width: 150px;
    height: 150px;
    line-height: 150px;
  }
  
  .action-buttons {
    flex-direction: column;
  }
  
  .action-buttons .el-button {
    width: 100%;
  }
}
</style>